//---------------------------------------------------------------------------
/**
 * \class CObject
 * \brief This is a basic class for using with CSmartTemplate class.
 * \version 0.1
 *
 * \author Woo-Hyun Kim (woorung@nhncorp.com, woorung@gmail.com)
 * \author http://blog.naver.com/wisereign .
 *
 * \date 2007/09/04
 */
//---------------------------------------------------------------------------
#ifndef CObjectH
#define CObjectH
//-----------------------------------------------------------------
#include <iostream>
//-----------------------------------------------------------------
using namespace std;
//----------------------------------------------------------------
// Remark:
//    All the classes derived from CObject must implement
//    copy constructor, 
//    assign operator, 
//    clone() function,
//    equals-related functions(blindlyEquals(), getTypeEquiv()).
//----------------------------------------------------------------
class CObject {
private:
	time_t ttl;
	
protected:
	virtual bool blindlyEquals(const CObject *rhs) const {
		return true; // default to stop the chaining
	};
	//virtual const type_info *getTypeEquiv() const = 0;
	virtual const type_info *getTypeEquiv() const {
		return &typeid(this);
	};

public:
	CObject() {};
	CObject(const CObject &rhs) { 
		clone();
	};
	virtual ~CObject() {};

	virtual CObject *clone() const { 
		return clone(); 
	};

	virtual CObject *newInstance() const { 
		return clone(); 
	};

	virtual CObject &operator=(const CObject &rhs) { 
		// identity test
		if(this==&rhs) return *this;

		return *clone(); 
	};
	bool operator==(const CObject &rhs) const {
		bool isEqual = false;

		if((&rhs!=NULL)&&(*(this->getTypeEquiv())==*(rhs.getTypeEquiv()))) {
			isEqual = (this->blindlyEquals(&rhs));
		}
		// --------------------------------------------------------
		// # Attention
		// If you want to inspect exact types, erase the following else stmt.
		// However, in some cases, it is useful to inspect without type check
		// --------------------------------------------------------
		else {
			isEqual = (this->blindlyEquals(&rhs));
		}
		// --------------------------------------------------------

		return isEqual;
	};

	time_t getTTL() const { return ttl; };
	void setTTL(time_t ttl) { this->ttl = ttl; };
};
//----------------------------------------------------------------
#endif
